/*
 * @Author: 我想吃余 483766615@qq.com
 * @Date: 2025-11-10 08:36:35
 * @LastEditors: 我想吃余 483766615@qq.com
 * @LastEditTime: 2025-11-11 11:25:09
 * @FilePath: /code/oscode/mutual/ticket_grab.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include <iostream>
#include <vector>
#include <pthread.h>
#include <unistd.h>
#include "lockguard.hpp"

using namespace std;

class thread_data
{
public:
    thread_data(int number)
    {
        _threadname = "Thread-" + to_string(number);
    }

public:
    string _threadname;
};

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; // 定义一把锁
int tickets = 1000;                               // 总票数

void *get_ticket(void *arg)
{
    thread_data *td = (thread_data *)arg;
    while (true)
    {
        {//临界区
            LockGuard lg(&lock);
            // pthread_mutex_lock(&lock);//有锁的才能运行接下来的代码，否则阻塞等待
            if (tickets > 0)
            {
                usleep(1000);
                printf("%s get a ticket %d\n", td->_threadname.c_str(), tickets);
                tickets--;
                // pthread_mutex_unlock(&lock);
            }
            else
            {
                // pthread_mutex_unlock(&lock);
                break;
            }
        }
        usleep(13); // 模拟一个线程解锁后需要做一些其他事情，避免该线程竞争锁能力过强而导致其他线程拿不到锁。
    }
    return nullptr;
}

int main()
{
    // 创建5个线程
    vector<pthread_t> tids;
    vector<thread_data *> tds;
    for (int i = 1; i <= 5; ++i)
    {
        pthread_t tid;
        thread_data *td = new thread_data(i);
        tds.push_back(td);
        pthread_create(&tid, nullptr, get_ticket, tds[i - 1]);
        tids.push_back(tid);
    }

    for (int i = 1; i <= 5; ++i)
    {
        pthread_join(tids[i - 1], nullptr);
        delete tds[i - 1];
        cout << "Thread-" << i << "quit!" << endl;
    }

    return 0;
}